home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Fritz: All Fritz
/
All Fritz.zip
/
All Fritz
/
FILES
/
UTILREEN
/
PRNTUTIL.LZH
/
SPS.8
< prev
next >
Wrap
Text File
|
1987-05-02
|
16KB
|
439 lines
;SPS.COM is a TSR program to do a selective print screen. It prints
;the characters within a box defined by the cursor position. When
;started, if P is pressed, the whole screen is printed, and if Esc
;is pressed, the print screen is aborted.
Colormem equ 0B800h ;Color video mem for page 1
Monomem equ 0B000h ;Mon video mem for page 1
Timer equ 8 ;Timer int #
Enterkey equ 28 ;Define scan codes
Home equ 71
Endkey equ 79
Esc equ 1
Lfarrow equ 75
Rtarrow equ 77
Uparrow equ 72
Dnarrow equ 80
Pgup equ 73
Pgdn equ 81
Cntrl equ 29 ;Scan code for control key
Cntnot equ Cntrl+128 ;Scan code fpr control key release
Lshrel equ 42+128 ;Scan code for left shift release
Rshrel equ 54+128 ; " " " right " "
Video equ 10h ;Bios video interrupt
DOS equ 21h ;DOS interrupt
Getvec equ 35h ;Get int vector DOS service
Setvec equ 25h ;Set int vector DOS service
Setcur equ 2 ;Set cursor pos video service
Getcur equ 3 ;Get cursor pos video service
Promptpos equ 25*160-36 ;5th char from end of screen
jmp Initialize ;Install the program as int 5 (PrtScn)
Oldint5:
Oldoff5 dw ? ;Save old int 5 offset and segment here
Oldseg5 dw ?
Oldint8:
Oldoff8 dw ?
Oldseg8 dw ?
Oldint9:
Oldoff9 dw ? ;Save old keyboard int here
Oldseg9 dw ?
Vidmem dw ? ;Current video mem segment
Curpos dw ? ;Cursor position at start
Curtyp dw ? ;Cursor type
Stloc dw 0 ;Start row:col of print box
Endloc dw 184fh ;End row:col of print box
Timeval db ?
Vpage db ? ;Current video page
Endflg db 0 ;1=> start row:col set
Prtflg db 0 ;1=> screen has been printed
Cntflg db 0 ;1=> Cntrl being pressed
Row db ? ;Rows to print
Col db ? ;Columns to print
Buffer: dw 18 dup(?) ;Put original prompt data here
Msg1: db 'Speptp psptpaprptp pppopspiptpipopnp'
Msg2: db 'Speptp pepnpdp pppopspiptpipopnp p p'
Msg3: db 'Pprpipnptpeprp pnpoptp prpepapdpyp p'
Rowbuf: db 83 dup(?) ;Buffer for a screen row of chars
Newint5: push bp,ax,bx,cx,dx,si,di,ds,es ;Save all for calling pgm
mov bp,sp
mov ds,cs ;Set both for this code
mov es,cs
mov cx,Colormem ;Assume color display
mov ah,15 ;Get current video mode
int Video
mov Vpage,bh ;Save video page
cmp al,2 ;Color?
je A1 ;Yes
cmp al,3 ;Color?
je A1 ;Yes
cmp al,7 ;Mono?
je A0 ;Yes
mov sp,bp
pop es,ds,di,si,dx,cx,bx,ax,bp ;Restore all for calling pgm
cs jmp far d[Oldint5] ;and do a graphics print screen
;Come here if 80 col text mode.
A0: mov cx,Monomem ;Yes, set for Mono
A1: mov bl,0 ;bx=page offset
add cx,bx ;Video segment
mov Vidmem,cx ;Save it
;Save old and install new Keyboard int 9 and Timer int 8 to this code.
push ds
mov ax,0 ;Set ds=0 (int area)
mov ds,ax
cli ;Disable interrupts
mov ax,[32]
mov bx,[34]
mov cx,[36]
mov dx,[38]
mov cs:Oldoff8,ax
mov cs:Oldseg8,bx
mov cs:Oldoff9,cx ;to storage
mov cs:Oldseg9,dx
mov w[32],Newint8
mov w[34],cs
mov w[36],Newint9
mov w[38],cs
sti ;Enable ints
pop ds
;Initialize variables.
mov Stloc,0 ;Start of screen
mov Endloc,184Fh ;End of screen
mov Endflg,0 ;Clear flags
mov Prtflg,0
mov Cntflg,0
;Get current Cursor position and type.
mov ah,Getcur ;Get cursor row:col
mov bh,Vpage
int Video
mov Curpos,dx ;Save it
mov Curtyp,cx ;Save cursor type
;Move cursor to top of screen.
xor dx,dx ;Top of screen
call Poscur
mov cx,0607h ;Set new cursor
mov ah,1
int Video
;Get last 18 bytes from screen.
push ds
mov ax,Vidmem ;Set ds=Vidmem
mov ds,ax
mov si,Promptpos ;ds:si=prompt pos
mov di,Buffer ;es:di=buffer
mov cx,18 ;Get 18 words
rep movsw ;to buffer
pop ds
;Display prompt.
mov si,Msg1 ;Print 'start' prompt
call Prompt
;Hang up computer and wait for keyboard input.
Waithere: jmp Waithere ;Wait for keyboard int
Newint8:
cs cmp Timeval,0
je X1
cs dec Timeval
X1: cs jmp far d[Oldint8]
;This is the new Keyboard int 9 routine. Does not pass keys on to
;other programs, so they never know keys were pressed.
Newint9: sti
push ax ;Save reg
in al,60h ;Get scan code
cmp Prtflg,0 ;Is screen being printed?
jne B0 ;Yes, clear keyboard and return from int
cmp al,Lshrel ;Left shift release?
je A2 ;Yes
cmp al,Rshrel ;Right shift release?
jne A3 ;No
A2: pop ax
cs jmp far d[Oldint9] ;Yes, send to BIOS
;No, process the key command.
A3: cmp al,Home ;Home?
jne C1 ;No
xor dx,dx ;Set for start of screen
B1: call Poscur ;Set cursor there
;Reset keyboard and sen End Of Interrupt
B0: call Resetkbd ;Reset keyboard
pop ax
iret ;Send back to Wait line
C1: cmp al,Endkey ;End key?
jne C2 ;No
mov dx,184Fh ;Set for end of screen
jmp B1
C2: cmp al,Uparrow ;Up arrow?
jne C3 ;No
cmp dh,0 ;On top line?
je B0 ;Yes
dec dh ;Dec row
jmp B1
C3: cmp al,Dnarrow ;Down arrow?
jne C4 ;No
cmp dh,24 ;On bottom row?
je B0 ;Yes
inc dh ;Inc row
jmp B1
C4: cmp al,Lfarrow ;Left arrow?
jne C5 ;No
cmp cs:Cntflg,0 ;Cntrl left arrow?
je C4A ;No
mov dl,0 ;Set for 1st col
jmp B1
C4A: cmp dl,0 ;At 1st col?
je B0 ;Yes
dec dl ;Dec col
jmp B1
C5: cmp al,Rtarrow ;Right arrow?
jne C6 ;No
cmp cs:Cntflg,0 ;Cntrl right arrow?
je C5A ;No
mov dl,79 ;Set for last col
jmp B1
C5A: cmp dl,79 ;At last col?
je B0 ;Yes
inc dl ;Inc col
jmp B1
C6: cmp al,Cntrl ;Control pressed?
jne C7 ;No
inc Cntflg ;Yes, set flag
jmp B0
C7: cmp al,Cntnot ;Cntrl key released?
jne C8 ;No
mov Cntflg,0 ;Clear flag
jmp B0
C8: cmp al,Esc ;Escape?
jne C9 ;No
jmp Exit ;Yes, exit
C9: cmp al,25 ;Was a P?
je Check ;Yes, print whole screen
cmp al,Pgup ;Page up?
jne D1 ;No
mov dh,0 ;Set to top row
jmp B1
D1: cmp al,Pgdn ;Page down
jne D3 ;No
mov dh,24 ;Set to last row
D2: jmp B1
D3: cmp al,Enterkey ;Enter?
jne D2 ;No, ignore the key and wait for another
cmp Endflg,0 ;1st selection?
jne D4 ;No
mov Stloc,dx ;Save start box location
inc Endflg ;=> start saved
mov si,Msg2 ;Print End prompt
call Prompt
jmp B0 ;Get next command
D4: mov Endloc,dx ;Save end location
Check: mov si,Buffer ;ds:si=buffer
call Prompt ;Put original data back on screen
inc Prtflg ;Indicate printing has started
mov ax,Stloc ;Get box start
mov cx,Endloc ;Get box end
sub ch,ah ;Rows OK?
jc Exit ;No
sub cl,al ;Cols OK?
jc Exit ;No, exit
add cx,0101h ;ah=rows, al=columns to do
mov Row,ch ;Save them
mov Col,cl
;Compute start offset.
mov cl,al ;Save column
mov ch,80 ;Chars/row
xchg al,ah ;Get row to al
mul ch ;ax=char offset to start of row
mov ch,0 ;cx=column
add ax,cx ;ax=char offset of start location
shl ax,1 ;Byte offset since 2 bytes/char
mov si,ax ;Save it
;Get a row of data to the buffer.
E0: push ds
mov ax,Vidmem ;Set ds=video mem
mov ds,ax
mov es,cs ;Set es this segment
E1: mov cl,cs:Col ;Get cols to do
mov ch,0 ;cx=cols to do
mov di,Rowbuf ;es:di point to screen row buffer
push si,di,cx ;Save pointers and count
E2: lodsw ;Get char & attr from screen
stosb ;Save char in row buffer
loop E2 ;Do for all chars on row
mov ax,0A0Dh ;Add a cr-lf
stosw
;Ckeck for and replace (with a space) any control chars.
pop cx,di ;Get cols and buffer pointer
E3: mov al,cs:[di] ;Get a char from buffer
cmp al,20h ;Control char?
jb E4 ;Yes
cmp al,0FFh ;Bad char?
jb E5 ;No
E4: mov cs:b[di],20h ;Replace with a space
E5: inc di ;Point to next char
loop E3 ;Check all
;Now send chars in buffer to printer.
call Printer
pop si ;Get start of row
add si,160 ;Next row
dec cs:Row ;Done all rows?
jne E1 ;No
pop ds
;Now exit.
Exit: mov si,Buffer ;Put old screen data back
call Prompt
mov dx,cs:Curpos ;Restore Cursor
call Poscur
mov cx,cs:Curtyp
mov ah,1
int Video
;Set old keyboard and timer interrupts back.
mov ax,0 ;Set ds=0 (int area)
mov ds,ax
cli ;Disable interrupts
mov ax,cs:Oldoff8 ;Set old int 8
mov bx,cs:Oldseg8
mov cx,cs:Oldoff9 ;Set old int 9
mov dx,cs:Oldseg9
mov [32],ax
mov [34],bx
mov [36],cx
mov [38],dx
sti ;Enable ints
call Resetkbd ;Reset the keyboard
mov sp,bp
pop es,ds,di,si,dx,cx,bx,ax,bp ;Restore all for calling pgm
iret ;Return from interrupt
;Subroutines ---------------------------------------------------------
Poscur: mov ah,Setcur ;Set cursor video service
mov bh,Vpage ;Current video page
int Video ;Set cursor pos
ret
Prompt: push ax,cx,es,di
mov ax,Vidmem ;Set es=Video segment
mov es,ax
mov di,Promptpos ;es:di=prompt pos
mov cx,18 ;18 words to move
rep movsw ;Move them to video mem
pop di,es,cx,ax
ret
Getkey: mov ah,0 ;Wait for key Keyboard service
int 16h ;Do it
ret
Resetkbd: in al,61h ;Get current control value
mov ah,al ;Save it in ah
or al,80h ;Set msb
out 61h,al ;Send it to control port
mov al,ah ;Get original value
out 61h,al ;Send it to control port
cli ;Disable ints
mov al,20h ;Send EOI value to 8259
out 20h,al
sti ;Enable ints
ret
;Print the row of chars in the row buffer.
Printer: push ds
xor dx,dx ;Select LPT1
mov ds,cs ;Set ds this code
mov Timeval,36 ;Set a 2 second wait
G1: call Getstat ;Get printer status
cmp ah,90h ;OK?
je G3 ;Yes
cmp Timeval,0 ;Timed out?
jne G1 ;No
call PNR ;Print 'Printer not ready' prompt
mov Timeval,180 ;Set a 10 second wait
G2: call Getstat ;Get printer status
cmp ah,90h ;OK now?
je G8 ;Yes
cmp Timeval,0 ;Timed out?
jne G2 ;No
jmp Exit ;Yes, give up
G8: call PIB ;Put old screen back
G3: mov si,Rowbuf ;ds:si points to row buffer
mov cl,Col ;cx=Columns
mov ch,0
add cl,2 ;Add 2 for cr-lf at end
G4: lodsb ;Get a char from buffer
mov ah,0 ;Send char service
int 17h ;no, send to printer
test ah,10h ;Still selected?
je G7 ;No
loop G4 ;Yes, print next char
pop ds
ret
G7: push si,cx ;Save position and count
mov Timeval,180 ;Set a 10 second timeout
call PNR ;Print 'Printer not ready'
G5: call Getstat ;Get printer status
test ah,10 ;Selected?
jne G6 ;Yes
cmp Timeval,0 ;Timed out?
jne G5 ;No
jmp Exit ;Yes, give up
G6: call PIB ;Put old screen back
pop cx,si ;Get old position and count
jmp G4 ;and continue printing
Getstat: mov ah,2
int 17h
ret
PNR: push si
mov si,Msg3
PNR1: call Prompt
pop si
ret
PIB: push si
mov si,Buffer
jmp PNR1
;Come here to install the program. ------------------------------------
Initialize: jmp short Init1
Msg4: db 13,10,'Selective Print Screen ver. 2.0 by Bob Montgomery'
db ' installed.',13,10,'$'
Init1: mov ah,Getvec
mov al,5
int DOS
mov [Oldoff5],bx
mov [Oldseg5],es
mov ah,Setvec
mov al,5
mov dx,Newint5
int DOS
mov dx,Msg4
mov ah,9
int DOS
mov dx,Initialize
int 27h